package org.sky.sys.util.multipledatabase.connect;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.alibaba.druid.pool.DruidPooledConnection;
import org.apache.logging.log4j.Logger;
import org.sky.util.LogUtils;
import org.yaml.snakeyaml.Yaml;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Map;
import java.util.Properties;

/**
 * @author weifx
 * @Title: connect
 * @ProjectName springboot-platform
 * @Description: TODO{多数据源连接池配置}
 * @date 2019/4/16 11:53
 * @Version 1.0
 */
public class DBConnectionPool {
    private static Logger logger = LogUtils.getLogger(DBConnectionPool.class);
    private static DruidDataSource druidDataSource = null;
    /**
     * YML配置文件名称
     */
    private static final String ymlName = "config.yml";
    /**
     * 默认连接池连接参数
     */
    private static Properties extProperties = null;
    static {
        try {
            Yaml applicationYml = new Yaml();
            //加载配置文件
            Map appYml = applicationYml.load(DBConnectionPool.class.getClassLoader().getResourceAsStream(ymlName));
            extProperties = getDruidProperties((Map<String,Object>)appYml.get("multiple-druid"));
        } catch (Exception e) {
            logger.error("获取配置失败",e);
        }
    }

    /**
     * 创建连接池
     * @param databseProperties
     */
    public DBConnectionPool (Properties databseProperties){
        extProperties.putAll(databseProperties);
        try {
            druidDataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(extProperties); //DruidDataSrouce工厂模式
        }catch (Exception e){
            logger.error("创建数据库连接池出错:{}",e.getMessage());
        }
    }
    /**
     * 返回druid数据库连接
     * @return
     * @throws SQLException
     */
    public DruidPooledConnection getConnection() throws SQLException{
        return druidDataSource.getConnection();
    }
    /**
     * 关闭连接:<br/>
     * 使用完后必须con.close()掉，
     * 使用连接池的话，执行con.close并不会关闭与数据库的TCP连接，而是将连接还回到池中去，
     * 如果不close掉的话，这个连接将会一直被占用，直接连接池中的连接耗尽为止。
     * @param resultSet
     * @param statement
     * @param connection
     */
    public static void closeConnect(ResultSet resultSet, Statement statement, Connection connection){
        try {
            if (null != resultSet && !resultSet.isClosed()) {
                resultSet.close();
            }
            if (null != statement && !statement.isClosed()) {
                statement.close();
            }
            if (null != connection && !connection.isClosed()) {
                connection.close();
            }
        }catch (Exception e){
            logger.error("关闭连接时出错{}",e);
        }
    }
    /**
     * Map解析成Properties
     * @param databaseMap
     * @return
     */
    private static Properties getDruidProperties(Map<String,Object> databaseMap) {
        if (null == databaseMap || databaseMap.isEmpty()){
            logger.error("yml database 为空");
            throw new IllegalArgumentException("yml database 为空");
        }
        Properties p =null;
        try {
            p = new Properties();
            for (Map.Entry<String,Object> entry : databaseMap.entrySet()) {
                p.setProperty(entry.getKey(),entry.getValue().toString());
            }
        } catch (Exception e) {
            logger.error("datasource解析propreties出错{}",e);
            e.printStackTrace();
        }
        return p;
    }
}